package org.imraniqbal.mouseland;

import org.imraniqbal.engine.Direction;
import org.imraniqbal.engine.Game;
import org.imraniqbal.engine.GameFrame;
import org.imraniqbal.engine.GameController.Controls;
import org.imraniqbal.engine.GameEvent;
import org.imraniqbal.engine.Map;

/**
 * @author  imran
 */
public class MouselandGame extends Game {
	
	private int NUM_MICE = 4;
	/**
	 * @uml.property  name="hero"
	 * @uml.associationEnd  
	 */
	private Hero hero;
	/**
	 * @uml.property  name="mice"
	 * @uml.associationEnd  multiplicity="(0 -1)"
	 */
	private Mouse[] mice;
	/**
	 * @uml.property  name="ladder"
	 * @uml.associationEnd  
	 */
	private Exit ladder;
	/**
	 * Creates a new mouseland Game
	 * @author imran
	 */
	public MouselandGame() {
		super();
		start();
	}
	/**
	 * Initializes a game by setting the map, win condition, player and mice
	 * @author imran
	 */
	@Override
	public void start() {
		setWin(false);
		this.setMap(new Map("/maps/mouseland/mouselandMap.txt"));
		
		ladder = new Exit(18, 1);
		getMap().addMappable(ladder);
		
		hero = new Hero(9,9,Direction.UP,1); //add Hero
		hero.spawn(getMap());
		addListener(hero);
		
		mice = new Mouse[NUM_MICE];
		for (int i=0; i<NUM_MICE; i++){ //add mice
			mice[i] = new Mouse(i+8,5,Direction.DOWN,1, i+1);
			mice[i].spawn(getMap());
			addListener(mice[i]);
		}
	}

	/**
	 * Checks to see if game has ended
	 * @return boolean, true if game has ended, false otherwise
	 * @author imran
	 */
	@Override
	public boolean hasEnded() {
		return (getWin() || hero.getNumOflives() == 0) ;
	}

	/**
	 * Makes game update based on input
	 * @author imran
	 */
	@Override
	public void getControl(Controls control) {
		if(hasEnded()){ return; }
		switch (control) {
		case LEFT:
			hero.setDirection(Direction.LEFT);
			break;
		case RIGHT:
			hero.setDirection(Direction.RIGHT);
			break;
		case UP:
			hero.setDirection(Direction.UP);
			break;
		case DOWN:
			hero.setDirection(Direction.DOWN);
			break;
		case ACTION:
			hero.layTrap(this.getMap());
			return;
		}
		hero.updateLocation(getMap());
		for(Mouse mouse: mice){
			mouse.moveMice(hero, getMap());
		}
		notify(new GameEvent(this));
	}
	
	public static void main(String args[]) {
		MouselandGame tempGame = new MouselandGame(); //create the game
		new GameFrame("Mouseland",new MouselandPanel(tempGame)); //set up the frame
	}

}
